<template>
  <div id="wrap">
    <div id="chart-wrap">
      <div id="chart-palette"></div>
      <div id="chart-diagram"></div>
    </div>
    <button @click="onSubmit"></button>
  </div>
</template>

<script>
  //import go from "../assets/js/go"
  import "@/assets/js/go.js";
  //import go from "gojs"
  const MAKE = go.GraphObject.make; //创建一个GoJS对象
  export default {
    data() {
      return {}
    },
    mounted() {



      var mySelf = this;
      mySelf.myDiagram = MAKE(go.Diagram, "chart-diagram", {  //chart-diagram同HTML中画布DIV的id一致
        initialContentAlignment: go.Spot.Center, // 居中显示
        "undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作
        "toolManager.hoverDelay": 100, //tooltip提示显示延时
        "toolManager.toolTipDuration": 10000, //tooltip持续显示时间
        //isReadOnly:true,//只读
        "grid.visible": true, //显示网格
        allowMove: true, //允许拖动
        // allowDragOut:true,
        allowDelete: true, //是否允许删除
        allowCopy: true,  //是否允许复制
        allowClipboard: true,  //是否允许粘贴
        "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小，而不是向上和向下滚动
        mouseDrop: function(e) {
          e.diagram.currentTool.doCancel();  // 要拖放到组中才能成功创建节点
        },
        /*layout: MAKE(go.TreeLayout, {
          angle: 0,
          layerSpacing: 35
        })*/
      }); //构建gojs对象
      mySelf.myDiagram.addDiagramListener("ObjectSingleClicked", function(e) {
        //监听元素点击事件

        console.log(e.subject.part);

      });

      mySelf.myDiagram.addDiagramListener("BackgroundSingleClicked", function(e) {
        //监听背景点击事件
        console.log("Double-clicked at" + e.diagram.lastInput.documentPoint);
      });
      mySelf.myDiagram.addDiagramListener("externalobjectsdropped", function(e) {
        e.subject.each(function(n){
//得到从Palette拖过来的节点
          /*console.log(n)
          console.log(n.data.key);*/
        });
      });

      mySelf.myDiagram.addDiagramListener("ClipboardPasted", function(e) {
        //监听粘贴事件
        console.log("Pasted" + e.diagram.selection.count + "parts");
      });


      mySelf.myDiagram.linkTemplate = MAKE(go.Link, {
          routing: go.Link.AvoidsNodes,
          curve: go.Link.JumpGap, //JumpOver:连线弧形交叉；JumpGap：连线不交叉
          corner: 5,
          toShortLength: 4,
          relinkableFrom: true,
          relinkableTo: true,
          reshapable: true,
          resegmentable: true,
          // mouse-overs subtly highlight links:
          /*mouseEnter: function(e, link) {
            link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)";
          },
          mouseLeave: function(e, link) {
            //link.findObject("HIGHLIGHT").stroke = "transparent";
          }*/
        },
        new go.Binding("points").makeTwoWay(),
        MAKE(go.Shape, {
          strokeWidth: 2,
          stroke: "#F60"
        }),
        MAKE(go.Shape, {
          toArrow: "Standard",
          fill: "red",
          stroke: "blue"
        }), //箭头
        MAKE(go.TextBlock, {
            margin: 20,
            stroke: "blue",
            font: "14px sans-serif",
            width: 50,
            wrap: go.TextBlock.WrapDesiredSize
          },
          new go.Binding("text", "linktext")), {
          toolTip: MAKE(go.Adornment, "Auto",
            MAKE(go.Shape, {
              fill: "transparent",
              stroke:"transparent"
            }),
            MAKE(go.TextBlock, {
              margin: 4
            }, new go.Binding("text", "name1"))
          ) // end of Adornment
        }
      );
      mySelf.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal; //设置拖出的连线可自动计算线的样式
      mySelf.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal; //连接前：设置拖出的连线可自动计算线的样式
      let myModel = MAKE(go.GraphLinksModel); //也可以创建link model;需要配置myModel.linkDataArray 如下
      /*function sameColor(fromnode, fromport, tonode, toport) {
        console.log(fromnode, fromport, tonode, toport)
        return fromnode.data.color !== tonode.data.color;
      }
      mySelf.myDiagram.toolManager.linkingTool.linkValidation = sameColor;
      mySelf.myDiagram.toolManager.relinkingTool.linkValidation = sameColor;*/
      myModel.nodeDataArray = [
        {"key":1,"loc":"100 100", "isGroup":true, "text":"Main 1", "horiz":true},
        {"key":2,"loc":"100 100", "isGroup":true, "text":"Main 2", "horiz":true},
        {"key":3, "isGroup":true, "text":"Group A", "group":1},
        {"key":4, "isGroup":true, "text":"Group B", "group":1},
        {"key":5, "isGroup":true, "text":"Group C", "group":2},
        {"key":6, "isGroup":true, "text":"Group D", "group":2},
        {"key":7, "isGroup":true, "text":"Group E", "group":6},
        {"text":"first A", "group":3, "key":-7},
        {"text":"second A", "group":3, "key":-8},
        {"text":"first B", "group":4, "key":-9},
        {"text":"second B", "group":4, "key":-10},
        {"text":"third B", "group":4, "key":-11},
        {"text":"first C", "group":5, "key":-12},
        {"text":"second C", "group":5, "key":-13},
        {"text":"first D", "group":6, "key":-14},
        {"text":"first E", "group":7, "key":-15}
      ];
      myModel.linkDataArray = [];
      var lightText = "whitesmoke";
      mySelf.myDiagram.groupTemplate =
        MAKE(go.Group, "Auto",
          {
            background: "transparent",
            ungroupable: true,
            // highlight when dragging into the Group
            mouseDragEnter: function(e, grp, prev) { highlightGroup(e, grp, true); },
            mouseDragLeave: function(e, grp, next) { highlightGroup(e, grp, false); },
            computesBoundsAfterDrag: true,
            // when the selection is dropped into a Group, add the selected Parts into that Group;
            // if it fails, cancel the tool, rolling back any changes
            mouseDrop: finishDrop,
            handlesDragDropForMembers: true,  // don't need to define handlers on member Nodes and Links
            // Groups containing Groups lay out their members horizontally
            //layout: makeLayout(false),
            selectable: true,
            selectionObjectName: "SHAPE",
            layout: MAKE(go.GridLayout, // automatically lay out the lane's subgraph
              {
                wrappingColumn: 1,
                cellSize: new go.Size(1, 1),
                spacing: new go.Size(25, 25),
                alignment: go.GridLayout.Position,
                comparer: function(a, b) { // can re-order tasks within a lane
                  var ay = a.location.y;
                  var by = b.location.y;
                  if (isNaN(ay) || isNaN(by)) return 0;
                  if (ay < by) return -1;
                  if (ay > by) return 1;
                  return 0;
                }
              }),
            click: function(e, grp) { // allow simple click on group to clear selection
              if (!e.shift && !e.control && !e.meta) e.diagram.clearSelection();
            },
            computesBoundsAfterDrag: false, // needed to prevent recomputing Group.placeholder bounds too soon
            handlesDragDropForMembers: true, // don't need to define handlers on member Nodes and Links
            mouseDragEnter: function(e, grp, prev) {
              highlightGroup(grp, true);
            },
            mouseDragLeave: function(e, grp, next) {
              highlightGroup(grp, false);
            },
            mouseDrop: function(e, grp) { // dropping a copy of some Nodes and Links onto this Group adds them to this Group
              // don't allow drag-and-dropping a mix of regular Nodes and Groups
              if (e.diagram.selection.all(function(n) {
                return !(n instanceof go.Group);
              })) {
                var ok = grp.addMembers(grp.diagram.selection, true);
                if (!ok) grp.diagram.currentTool.doCancel();
              }
            },
            subGraphExpandedChanged: function(grp) {
              var shp = grp.selectionObject;
              if (grp.diagram.undoManager.isUndoingRedoing) return;
              if (grp.isSubGraphExpanded) {
                shp.width = grp._savedBreadth;
              } else { // remember the original width
                grp._savedBreadth = shp.width;
                shp.width = NaN;
              }
            }
          },
          new go.Binding("layout", "horiz", makeLayout),
          new go.Binding("background", "isHighlighted", function(h) {
            return h ? "rgba(255,0,0,0.2)" : "transparent";
          }).ofObject(),
          MAKE(go.Shape, "Rectangle",
            { fill: null, stroke: defaultColor(false), strokeWidth: 2 },//设置组的背景，边框颜色及大小
            new go.Binding("stroke", "horiz", defaultColor),
            new go.Binding("stroke", "color")),
          MAKE(go.Panel, "Vertical",  // title above Placeholder
            MAKE(go.Panel, "Horizontal",  // button next to TextBlock
              { stretch: go.GraphObject.Horizontal, background: defaultColor(false) },
              new go.Binding("background", "horiz", defaultColor),
              new go.Binding("background", "color"),
              /* MAKE("SubGraphExpanderButton",  //展开收起按钮
                 { alignment: go.Spot.Right, margin: 5 }),*/
              MAKE(go.TextBlock,  //标题文字和一些设置
                {
                  alignment: go.Spot.Left,
                  editable: true,
                  margin: 5,
                  font: defaultFont(false),
                  opacity: 0.75,  // allow some color to show through
                  stroke: "#404040"
                },
                new go.Binding("font", "horiz", defaultFont),
                new go.Binding("text", "text").makeTwoWay())
            ),  // end Horizontal Panel
            MAKE(go.Placeholder, //设置组的padding
              { padding: 15, alignment: go.Spot.TopLeft })
          ),  // end Vertical Panel
        );
      function highlightGroup(e, grp, show) {
        if (!grp||grp.constructor != Object) return;
        e.handled = true;
        if (show) {
          // cannot depend on the grp.diagram.selection in the case of external drag-and-drops;
          // instead depend on the DraggingTool.draggedParts or .copiedParts
          var tool = grp.diagram.toolManager.draggingTool;
          var map = tool.draggedParts || tool.copiedParts;  // this is a Map
          // now we can check to see if the Group will accept membership of the dragged Parts
          if (grp.canAddMembers(map.toKeySet())) {
            grp.isHighlighted = true;
            return;
          }
        }
        grp.isHighlighted = false;
      }
      function finishDrop(e, grp) {
        console.log(grp.diagram.selection)
        var ok = (grp !== null
          ? grp.addMembers(grp.diagram.selection, true)
          : e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true));
        if (!ok) e.diagram.currentTool.doCancel();
      }
      function makeLayout(horiz) {  // a Binding conversion function
        if (horiz) {
          return $(go.GridLayout,
            {
              wrappingWidth: Infinity, alignment: go.GridLayout.Position,
              cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4)
            });
        } else {
          return MAKE(go.GridLayout,
            {
              wrappingColumn: 1, alignment: go.GridLayout.Position,
              cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4)
            });
        }
      }
      function defaultColor(horiz) {  // a Binding conversion function
        return horiz ? "#FFDD33" : "#33D3E5";
      }
      function defaultFont(horiz) {  // a Binding conversion function
        return horiz ? "bold 18px sans-serif" : "bold 16px sans-serif";
      }
      mySelf.myDiagram.nodeTemplate =
        MAKE(go.Node, "Horizontal",
          { selectionChanged: nodeSelectionChanged },
//节点选中改变事件，nodeSelectionChanged为回调的方法名
          MAKE(go.Panel, "Auto",
            MAKE(go.Shape,//节点形状和背景颜色的设置
              { fill: "#1F4963", stroke: null }
            ),
            MAKE(go.TextBlock,
              { },
              new go.Binding("text", "key") )
          )
        );
      function nodeSelectionChanged(node) {
        console.log(node)
      }
      mySelf.myDiagram.nodeTemplateMap.add(
        "",
        MAKE(
          go.Node,
          "Spot",
          nodeStyle(),
          MAKE( //声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
            go.Panel, //表明需要创建一个panel面板对象
            "Auto", //页面布局为自动
            MAKE( //声明构建一个圆角矩形
              go.Shape,
              "RoundedRectangle", {
                fill: "#44CCFF",
                stroke: null,
                width: 120
              },
              new go.Binding("figure", "figure") //声明并创建一个新的图形
            ),
            MAKE( //声明一个可编辑文本域
              go.TextBlock, {
                font: "12pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                maxSize: new go.Size(160, NaN),
                //wrap: go.TextBlock.WrapFit, //文本域换行
                editable: true, //是否可编辑
                margin: 8,
                alignment: go.Spot.Center,
                wrap: go.TextBlock.WrapFit,
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        )
      );
      mySelf.myDiagram.nodeTemplateMap.add(
        "Start",
        MAKE(
          go.Node,
          "Spot",
          nodeStyle(),
          MAKE( //声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
            go.Panel, //表明需要创建一个panel面板对象
            "Auto", //页面布局为自动
            MAKE( //声明构建一个圆角矩形
              go.Shape,
              "Circle", {
                fill: "#79C900",
                stroke: null
              },
              new go.Binding("figure", "figure") //声明并创建一个新的图形
            ),
            MAKE( //声明一个可编辑文本域
              go.TextBlock, {
                font: "12pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                maxSize: new go.Size(160, NaN),
                //wrap: go.TextBlock.WrapFit, //文本域换行
                editable: true, //是否可编辑
                margin: 8,
                alignment: go.Spot.Center,
                wrap: go.TextBlock.WrapFit,
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        )
      );
      mySelf.myDiagram.nodeTemplateMap.add(
        "End",
        MAKE(
          go.Node,
          "Spot",
          nodeStyle(),
          MAKE( //声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
            go.Panel, //表明需要创建一个panel面板对象
            "Auto", //页面布局为自动
            MAKE( //声明构建一个圆角矩形
              go.Shape,
              "Circle", {
                fill: "#DC3C00",
                stroke: null
              },
              new go.Binding("figure", "figure") //声明并创建一个新的图形
            ),
            MAKE( //声明一个可编辑文本域
              go.TextBlock, {
                font: "12pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                maxSize: new go.Size(160, NaN),
                //wrap: go.TextBlock.WrapFit, //文本域换行
                editable: true, //是否可编辑
                margin: 8,
                alignment: go.Spot.Center,
                wrap: go.TextBlock.WrapFit,
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        )
      );
      function nodeStyle() {
        return [
          // The Node.location comes from the "loc" property of the node data,
          // converted by the Point.parse static method.
          // If the Node.location is changed, it updates the "loc" property of the node data,
          // converting back using the Point.stringify static method.
          new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          {
            // the Node.location is at the center of each node
            locationSpot: go.Spot.Center,
            isShadowed: true,
            shadowColor: "#888",
            // handle mouse enter/leave events to show/hide the ports
            mouseEnter: function (e, obj) { showPorts(obj.part, true); },
            mouseLeave: function (e, obj) { showPorts(obj.part, false); }
          }
        ];
      }
      function showPorts(node, show) {
        var diagram = node.diagram;
        if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
        node.ports.each(function(port) {
          port.stroke = (show ? "white" : null);
        });
      }
      //Node连接线
      function makePort(name, spot, output, input) {
        return MAKE(go.Shape, "Circle", {
          fill: "transparent",
          stroke: null, // this is changed to "white" in the showPorts function
          desiredSize: new go.Size(8, 8),
          alignment: spot,
          alignmentFocus: spot, // align the port on the main Shape
          portId: name, // declare this object to be a "port"
          fromSpot: spot,
          toSpot: spot, // declare where links may connect at this port
          fromLinkable: output,
          toLinkable: input, // declare whether the user may draw links to/from here
          cursor: "pointer" // show a different cursor to indicate potential link point
        });
      };
      mySelf.myDiagram.model = myModel;
      mySelf.init();
    },
    methods: {
      onSubmit() {

      },
      init() {
        var mySelf = this;
        window.myPalette = MAKE(
          go.Palette,
          "chart-palette", // must name or refer to the DIV HTML element
          {
            scrollsPageOnFocus: false,
            "animationManager.duration": 800, // slightly longer than default (600ms) animation
            nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
            model: new go.GraphLinksModel([
              // specify the contents of the Palette
              {
                category: "Start",
                text: "Start"
              },
              {
                text: "Step"
              },
              {
                text: "main",
                figure: "Diamond"
              },
              {
                category: "End",
                text: "End"
              }
            ])
          }
        );
      },
    }
  }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less" scoped>
  #form-wrap {
    padding: 20px 40px;
    // background-color: white;
    border: solid 1px rgb(244, 244, 244);
  }

  #submit {
    width: 102px;
    height: 40px;
    float: right;
    margin: 20px 5px 16px 0;
  }

  #chart-wrap {
    width: 100%;
    display: flex;
    justify-content: space-between;
    margin-bottom: 22px;

    #chart-palette {
      width: 180px;
      margin-right: 30px;
      background-color: white;
      border: solid 1px rgb(244, 244, 244);
    }

    #chart-diagram {
      flex-grow: 1;
      height: 720px;
      background-color: white;
      border: solid 1px rgb(244, 244, 244);
    }
  }

  #lateEntry {
    clear: both;
    background-color: rgb(255, 255, 255);
    border: solid 1px rgb(244, 244, 244);

    >span {
      display: inline-block;
      height: 50px;
      font-size: 16px;
      line-height: 50px;
      text-indent: 30px;
      letter-spacing: 0.8px;
      text-align: left;
      color: rgb(35, 35, 35);
      // border-bottom: 1px solid rgb(234, 234, 234);
    }
  }
</style>
